<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2021/08/28
 * Time: 23:38
 * @link http://www.lmterp.cn
 */

namespace app\admin\controller\cha;


use app\admin\controller\BaseController;
use app\common\library\Tools;
use app\common\model\Channel;
use app\common\model\ChannelCountryQuotation;
use app\common\model\ChannelCountrySettings;
use app\common\model\SysCountries;
use app\common\service\logistics\ChannelService;
use app\common\service\product\ProductService;
use think\facade\Validate;

/**
 * 渠道国家配置
 * Class SettingsController
 * @package app\admin\controller\cha
 */
class SettingsController extends BaseController
{
    /**
     * 国家配置列表
     * @date 2021/08/29
     * @author longli
     */
    public function index()
    {
        $this->assign("is_show_add", $this->user->hasPermissions("/cha/settings/add"));
        if($this->request->isAjax())
        {
            $settings = ChannelCountrySettings::with(["channel", "country"]);
            $this->searchModel($settings, [
                'eq' => ['channel_id', 'country_code', 'status'],
                'egt' => ['success_rate'],
                'elt' => ['avg_day'],
            ]);
            $settings->order("setting_id desc");
            $limit = $this->getPageSize();
            $settings = $settings->paginate($limit);
            $this->assign("is_show_delete", $this->user->hasPermissions("/cha/settings/delete"));
            $this->assign('list', $settings->getCollection());
            $this->assign('page', $settings->render());
            return $this->fetch('lists');
        }
        $this->assign("counties", SysCountries::getCodeNameCh());
        $this->assign("channel", Channel::getAll());
        $this->assign("status", ['否', '是']);
        return $this->fetch('index');
    }

    /**
     * 配置详情
     * @date 2021/08/29
     * @author longli
     */
    public function info()
    {
        $sid = $this->request->get("setting_id");
        if(empty($sid)) $this->error("非法请求");
        $settings = ChannelCountrySettings::where("setting_id", $sid)->with([
            "quotation" => function($query)
            {
                $query->order("start_weight");
            }
        ])->find();
        if(!$settings) $this->error("配置不存在");
        $this->assign('settings', $settings);
        return $this->fetch('info');
    }

    /**
     * 添加配置
     * @date 2021/08/29
     * @author longli
     */
    public function add()
    {
        $attrs = [];
        if($id = $this->request->request("setting_id"))
        {
            $settings = ChannelCountrySettings::get($id);
            $this->assign('settings', $settings);
            $attrs = \app\common\model\ChannelAttr::field(['attr_id', 'attr_name', 'code'])
                ->whereIn("attr_id", $settings->exclude_attr)
                ->select()
                ->toArray();
        }
        $this->assign("attrs", $attrs);
        $this->assign('channel', Channel::getAll());
        $this->assign('counties', SysCountries::getCodeNameCh());
        return $this->fetch('add');
    }

    /**
     * 保存配置
     * @date 2021/08/29
     * @author longli
     */
    public function save()
    {
        $service = ChannelService::getInstance();
        $quotation = [];
        if($this->request->isPost())
        {
            $json = $this->request->getContent();
            if(!Tools::isJson($json, $data)) $this->error("非法请求");
            $data = ProductService::getInstance()->parseRequestData($data);
            $settings = $data['settings'];
            $quotation = $data['quotation'];
            if(($sMsg = $this->validateSetting($settings)) !== true) $this->error($sMsg);
            if(($qMsg = $this->validateQuotation($quotation, $settings['channel_id'])) !== true) $this->error($qMsg);
            $settings['exclude_post_code'] = $service->postCodeRange($settings['exclude_post_code']);
            if(!isset($settings['status'])) $settings['status'] = ChannelCountrySettings::IS_NO;
        }
        else
        {
            $settings = $this->request->only(['status', 'setting_id'], 'get');
        }
        $service->addSetting($settings, $quotation)
            ? $this->success("操作成功")
            : $this->error("操作失败");
    }

    /**
     * 删除配置
     * @date 2021/08/29
     * @author longli
     */
    public function delete()
    {
        $ids = $this->request->get("ids");
        if(empty($ids)) $this->error("非法操作");
        ChannelCountrySettings::destroy($ids);
        ChannelCountryQuotation::destroy(function($query) use($ids)
        {
            $query->whereIn("setting_id", $ids);
        });
        $this->success("删除成功");
    }

    /**
     * 校验可走国家配置
     * @param array $data 校验信息
     * @return bool|string
     * @date 2021/08/30
     * @author longli
     */
    private function validateSetting(& $data)
    {
        Validate::extend("promiseCheck", function($value)
        {
            if(empty($value)) return true;
            $regex = '/^\d+\-?\d*$/';
            if(!preg_match($regex, $value)) return "承诺天数格式有误";
            return true;
        });
        $validate = Validate::make([
            'channel_id'  => "require",
            'country_code'  => "require",
            'promise_day' => "promiseCheck"
        ],[
            'channel_id.require' => '渠道必选',
            'country_code.require' => '国家必选',
        ]);
        if(!$validate->batch()->check($data)) return join(', ', $validate->getError());
        if(empty($data['status'])) $data['status'] = 0;
        return true;
    }

    /**
     * 校验报价单详情
     * @param array $data 校验信息
     * @param int $cid 渠道id
     * @return bool|string
     * @date 2021/08/30
     * @author longli
     */
    private function validateQuotation(& $data, $cid)
    {
        $validate = Validate::make([
            'price'                 => "require|gt:0",
            'start_weight'          => "require|egt:0",
            'end_weight'            => "require|gt:0",
            'max_length'            => "egt:0",
            'continue_weight'       => "egt:0",
            'continue_weight_price' => "egt:0",
            'register_price'        => "egt:0",
            'operation_price'       => "egt:0",
            'fuel_price'            => "egt:0",
            'customs_price'         => "egt:0",
            'backend_price'         => "egt:0",
            'tax_price'             => "egt:0",
            'other_price'           => "egt:0",
            'discount'              => "integer|between:0,101",
            'paobi'                 => "egt:0",
        ],[
            'price.require'               => '价格必填',
            'price.gt'                    => '价格必须大于0',
            'start_weight.require'        => '开始重量必填',
            'start_weight.egt'            => '开始重量必须大于等于0',
            'end_weight.require'          => '结束重量必填',
            'end_weight.gt'               => '结束重量必须大于0',
            'continue_weight.egt'         => '续重必须大于等于0',
            'continue_weight_price.egt'   => '续重费必须大于等于0',
            'max_length.egt'              => '最长边必须大于等于0',
            'register_price.egt'          => '挂号费必须大于等于0',
            'operation_price.egt'         => '操作费必须大于等于0',
            'fuel_price.egt'              => '燃油费必须大于等于0',
            'customs_price.egt'           => '清关费必须大于等于0',
            'backend_price.egt'           => '尾程派送费必须大于等于0',
            'tax_price.egt'               => '税费必须大于等于0',
            'other_price.egt'             => '附加费必须大于等于0',
            'paobi.egt'                   => '抛比必须大于等于0',
            'discount.integer'            => '折扣只能是整数',
            'discount.between'            => '折扣只能是1-100的整数',
        ]);
        $channel = Channel::get($cid);
        $index = array_keys($data)[0];
        $validateData = [];
        $fields = ['price', 'continue_weight', 'start_weight', 'end_weight', 'max_length', 'register_price', 'operation_price', 'fuel_price',
            'continue_weight_price', 'customs_price', 'backend_price', 'tax_price', 'other_price', 'discount', 'paobi', 'status', 'remark', 'quotation_id'];
        foreach($data[$index] as $k => $v)
        {
            $temp = [];
            foreach($fields as $field)
            {
                if(in_array($field, ['quotation_id', 'remark', 'discount']) && empty($data[$field][$k])) continue;
                $temp[$field] = isset($data[$field][$k])
                    ? $data[$field][$k]
                    : 0;
            }
            $validateData[] = $temp;
        }
        $error = [];
        foreach($validateData as $v)
        {
            if(!$validate->batch()->check($v)) $error[] = join(', ', $validate->getError());
            if($v['start_weight'] >= $v['end_weight']) $error[] = "开始重量【{$v['start_weight']}】必须小于结束重量【{$v['end_weight']}】";
            if($channel->getData('billing_type') == Channel::BILLING_TYPE_FIRST)
            {
                if($v['continue_weight_price'] == 0) $error[] = "续重价格必须大于0";
                if($v['continue_weight'] == 0) $error[] = "续重必须大于0";
            }
        }
        if(!empty($error)) return join(', ', $error);
        $data = $validateData;
        return true;
    }
}